package com.ews.onlineexchange.rest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import com.alibaba.fastjson.JSONObject;
import com.ews.onlineexchange.app.AppService;
import com.ews.onlineexchange.app.CustomMapper;
import com.ews.onlineexchange.app.PublicArticleListForApp;
import com.ews.onlineexchange.app.entity.BulletinStat;
import com.ews.onlineexchange.app.entity.SimpleArticle;
import com.ews.onlineexchange.app.entity.SimpleBulletin;
import com.ews.onlineexchange.app.entity.TempAttachment;
import com.ews.onlineexchange.app.entity.TempBulletin;
import com.ews.onlineexchange.controller.BulletinHome3;
import com.ews.onlineexchange.controller.StatExport;
import com.ews.onlineexchange.model.Article;
import com.ews.onlineexchange.model.Attachment;
import com.ews.onlineexchange.model.Bulletin;
import com.ews.onlineexchange.model.ChooseType;
import com.ews.onlineexchange.model.ServiceSupplier;
import com.ews.onlineexchange.model.Trade;
import com.ews.onlineexchange.service.AgreedBulletinList;
import com.ews.onlineexchange.service.AudittedBulletinList;
import com.ews.onlineexchange.service.BulletinService;
import com.ews.onlineexchange.service.CategoryList;
import com.ews.onlineexchange.service.PublicityBulletinList;
import com.ews.onlineexchange.service.UserService;
import com.ews.onlineexchange.service.ZfBulletinList;
import com.ews.onlineexchange.util.AttachmentUtils;
import com.ews.onlineexchange.util.WorkBookUtil;
import com.fasterxml.jackson.core.JsonProcessingException;

/**
 * 
 * 
 * @author
 *
 */
@Path( value = "/bulletin" )
@Transactional
public class BulletinRest {

	@Inject
	EntityManager			entityManager;

	@Inject
	UserService				userService;

	@Inject
	AudittedBulletinList	audittedBulletinList;

	@Inject
	PublicityBulletinList	publicityBulletinList;

	@Inject
	AgreedBulletinList		agreedBulletinList;

	@Inject
	BulletinHome3			bulletinHome3;

	@Inject
	CategoryList			categoryList;

	@Inject
	PublicArticleListForApp	publicArticleListForApp;

	@Inject
	BulletinService			bulletinService;

	/**
	 * 采购公告列表
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	@GET
	@Path( "/getAudittedBulletinList/{pageNumber}/{pageSize}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getAudittedBulletinList( @DefaultValue("1") @PathParam( "pageNumber" )int pageNumber,
			@DefaultValue("6") @PathParam( "pageSize" ) int pageSize ) throws Exception {
		CustomMapper mapper = new CustomMapper();
		audittedBulletinList.refresh();
		audittedBulletinList.setFirstResult( (pageNumber - 1) * pageSize );
		audittedBulletinList.setMaxResults( pageSize );
		Long totalcount = audittedBulletinList.getResultCount();
		List<Bulletin> bulletinList = audittedBulletinList.getResultList();
		List<SimpleBulletin> sBulletinList = appService.getSimpleBulletinList( bulletinList, "auditted" );
		JSONObject jsonnObject = new JSONObject();
		jsonnObject.put( "totalcount", totalcount );
		jsonnObject.put( "bulletinArr", sBulletinList );
		return mapper.writeValueAsString( jsonnObject );
	}

	/**
	 * 中选公示列表
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	@GET
	@Path( "/getPublicityBulletinList/{pageNumber}/{pageSize}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getPublicityBulletinList( @PathParam( "pageNumber" ) int pageNumber,
			@PathParam( "pageSize" ) int pageSize ) throws Exception {
		CustomMapper mapper = new CustomMapper();
		publicityBulletinList.refresh();
		publicityBulletinList.setFirstResult( (pageNumber - 1) * pageSize );
		publicityBulletinList.setMaxResults( pageSize );
		Long totalcount = publicityBulletinList.getResultCount();
		List<Bulletin> bulletinList = publicityBulletinList.getResultList();
		List<SimpleBulletin> sBulletinList = appService.getSimpleBulletinList( bulletinList, "publicity" );
		JSONObject jsonnObject = new JSONObject();
		jsonnObject.put( "totalcount", totalcount );
		jsonnObject.put( "bulletinArr", sBulletinList );
		return mapper.writeValueAsString( jsonnObject );
	}
	@Inject
	ZfBulletinList zfBulletinList;
	@GET
	@Path( "/getZfBulletinList/{pageNumber}/{pageSize}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getZfBulletinList( @DefaultValue("1")@PathParam( "pageNumber" ) int pageNumber,
			@DefaultValue("10")@PathParam( "pageSize" ) int pageSize ) throws Exception {
		CustomMapper mapper = new CustomMapper();
		zfBulletinList.refresh();
		zfBulletinList.setFirstResult( (pageNumber - 1) * pageSize );
		zfBulletinList.setMaxResults( pageSize );
		Long totalcount = zfBulletinList.getResultCount();
		List<Bulletin> bulletinList = zfBulletinList.getResultList();
		List<SimpleBulletin> sBulletinList = appService.getSimpleBulletinList( bulletinList, "zf" );
		JSONObject jsonnObject = new JSONObject();
		jsonnObject.put( "totalcount", totalcount );
		jsonnObject.put( "bulletinArr", sBulletinList );
		return mapper.writeValueAsString( jsonnObject );
	}
	
	/**
	 * 中选公示列表
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
	@GET
	@Path( "/getAgreedBulletinList/{pageNumber}/{pageSize}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getAgreedBulletinList( @PathParam( "pageNumber" ) int pageNumber,
			@PathParam( "pageSize" ) int pageSize ) throws Exception {
		CustomMapper mapper = new CustomMapper();
		agreedBulletinList.refresh();
		agreedBulletinList.setFirstResult( (pageNumber - 1) * pageSize );
		agreedBulletinList.setMaxResults( pageSize );
		Long totalcount = agreedBulletinList.getResultCount();
		List<Bulletin> bulletinList = agreedBulletinList.getResultList();
		List<SimpleBulletin> sBulletinList = appService.getSimpleBulletinList( bulletinList, "agreed" );
		JSONObject jsonnObject = new JSONObject();
		jsonnObject.put( "totalcount", totalcount );
		jsonnObject.put( "bulletinArr", sBulletinList );
		return mapper.writeValueAsString( jsonnObject );
	}
	
	
	
	@Inject
	AppService appService ;
	/**
	 * 获取公告详情
	 * 
	 * @param bulletinId
	 * @return
	 * @throws JsonProcessingException
	 * @throws Exception
	 */
	@GET
	@Path( "/getBulletinById/{bulletinId}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getBulletinById( @PathParam( "bulletinId" ) String bulletinId ) throws JsonProcessingException {
		CustomMapper mapper = new CustomMapper();
		bulletinHome3.setId( bulletinId );
		Bulletin bulletin = bulletinHome3.getInstance();
		
		TempBulletin b = appService.getTempBulletin( bulletin );
		return mapper.writeValueAsString( b );
	}

	/**
	 * 获取通知公告列表
	 * 
	 * @return
	 * @throws Exception
	 */
	@GET
	@Path( "/getCategoryListByName/{categoryName}/{pageNumber}/{pageSize}" )
	@Produces( "text/html; charset=UTF-8" )
	@Context
	public String getCategoryListByName( @PathParam( "categoryName" ) String categoryName,
			@PathParam( "pageNumber" ) int pageNumber, @PathParam( "pageSize" ) int pageSize ) throws Exception {
		CustomMapper mapper = new CustomMapper();
		String categoryId = categoryList.getNameMap().get( categoryName ).getId();
		publicArticleListForApp.setCategoryId( categoryId );
		publicArticleListForApp.refresh();
		publicArticleListForApp.setFirstResult( (pageNumber - 1) * pageSize );
		publicArticleListForApp.setMaxResults( pageSize );
		List<Article> articles = publicArticleListForApp.getResultList();
		Long totalcount = publicArticleListForApp.getResultCount();
		List<SimpleArticle> simpleArticles = new ArrayList<>();
		JSONObject jsonnObject = new JSONObject();
		jsonnObject.put( "totalcount", totalcount );
		for ( Article article : articles ) {
			SimpleArticle simpleArticle = new SimpleArticle();
			simpleArticle.setId( article.getId() );
			simpleArticle.setCreateDate( article.getCreateDate() );
			simpleArticle.setTitle( article.getTitle() );
			//
			// StringBuilder linkSb = new StringBuilder("/public/Article.xhtml?articleId=");
			// linkSb.append(article.getId());
			// List<Attachment> atts = article.getAttachment();
			// List<TempAttachment> tempAtts = new ArrayList<>();
			// for (Attachment attachment : atts) {
			// TempAttachment tempAtt = new TempAttachment();
			// tempAtt.setFileName(attachment.getFilename());
			// tempAtt.setId(attachment.getId());
			// tempAtts.add(tempAtt);
			// }
			// simpleArticle.setLink(linkSb.toString());
			simpleArticles.add( simpleArticle );
		}
		jsonnObject.put( "articleArr", simpleArticles );
		return mapper.writeValueAsString( jsonnObject );
	}
	@Inject
	AttachmentUtils attachmentUtils;
	@GET
	@Path( "/getArticleById/{articleId}" )
	@Produces( "application/json" )
	@Context
	public SimpleArticle getArticleById( @PathParam( "articleId" ) String articleId ) throws JsonProcessingException {
		SimpleArticle simpleArticle = new SimpleArticle();
		Article article = entityManager.find( Article.class, articleId );
		simpleArticle.setContent( article.getArticleData().getContent() );
		simpleArticle.setId( article.getId() );
		simpleArticle.setCreateDate( article.getCreateDate() );
		simpleArticle.setTitle( article.getTitle() );

		StringBuilder linkSb = new StringBuilder( "/public/Article.xhtml?articleId=" );
		linkSb.append( article.getId() );
		List<Attachment> atts = article.getAttachment();
		List<TempAttachment> tempAtts = new ArrayList<>();
		for ( Attachment attachment : atts ) {
			TempAttachment tempAtt = new TempAttachment();
			tempAtt.setFileName( attachment.getFilename() );
			tempAtt.setFullPath(attachmentUtils.getFullPath(attachment));
			tempAtt.setId( attachment.getId() );
			tempAtts.add( tempAtt );
		}
		simpleArticle.setLink( linkSb.toString() );
		simpleArticle.setAttachments( tempAtts );
		return simpleArticle;

	}
	
	@GET
	@Path("/canOfferPrice")
	@Produces("application/json")
	@Context
	public JSONObject canOfferPrice(@QueryParam("bulletinId") String bulletinId,@QueryParam("supplierId") String supplierId) {   
		
		Bulletin bulletin = entityManager.find(Bulletin.class, bulletinId);
		JSONObject json = new JSONObject();
		boolean canOfferPrice = true;
		int status  = 200;
		String errMsg = "";

		if(bulletin == null) {
			status = 500;
			errMsg = "获取公告信息失败，请联系管理员！";
		}else {
			ServiceSupplier supplier = entityManager.find(ServiceSupplier.class, supplierId);
			if(supplier == null) {
				status = 500;
				errMsg = "获取中介信息失败，请联系管理员！";
			}else {
				if ( bulletin.getChooseTime().before( new Date() ) )//超时
					canOfferPrice = false;
				//是中介、 已经报名、竞价选取
				if(!((bulletin.getWayOfChoose().equals(ChooseType.Price) ||bulletin.getWayOfChoose().equals(ChooseType.Average)) 
						&& BulletinService.isInVerifiedTrades(supplier,bulletin.getVerifiedTrades())) ) 
					canOfferPrice = false;
				
			}
		}
		json.put("canOfferPrice", canOfferPrice);
		json.put("status", status);
		json.put("errMsg", errMsg);
		return json;
	}
	

	@GET
	@Path( "/getBulletinStats" )
	@Produces( "application/json" )
	@Context
	public List<BulletinStat> getBulletinStats( @QueryParam( "year" ) Integer year,
			@QueryParam( "qualificationClassId" ) String qualificationClassId ) {

		return bulletinService.bulletinStat( year, qualificationClassId );
	}
	

	@GET    
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
	@Path( value = "/bulletinStats/export/{year}" )
	public Response exportBulletinStats( @PathParam( "year" ) Integer year ) throws IOException {
		List<BulletinStat> stats = (List<BulletinStat>)bulletinService.bulletinStat(year, null);	
		HSSFWorkbook workbook = StatExport.statExportForSupplier("按月份统计",1,stats,false,StatExport.FIELD_LABEL_BULLETIN,StatExport.FIELD_NAMES_BULLETIN);
		
		File tempFile = new File(WorkBookUtil.EXPORT_DATA_DEFAULT_PATH);
		if(!tempFile.exists()) {
			tempFile.createNewFile();
		}
		workbook.write(tempFile);		
		
		ResponseBuilder response = Response.ok( tempFile );
		response.header("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode( String.format( "按月份统计-%s.xls", year.toString() ), "UTF-8" ) );
		return response.build();
	}
	
	@GET    
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
	@Path( value = "/export/assessCandidateList/{id}" )
	public Response archive( @PathParam( "id" ) String id ) throws InvalidFormatException, IOException {
		Bulletin bulletin = bulletinService.getBulletinById( id );
		
		File file = export( bulletin );
		String fileName = String.format( "东营市网上中介超市【%s】项目评审选取候选名单", bulletin.getProjectName() )+".docx";
		
		ResponseBuilder response = Response.ok( file );
		response.header("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode( fileName, "UTF-8" ) );
		return response.build();
	}
	
	public File export( Bulletin bulletin ) throws IOException, InvalidFormatException {
		
		XWPFDocument document = new XWPFDocument();		
		
		File file = File.createTempFile( "onlineExchangeExport", ".docx" );
		
		file.deleteOnExit();
		FileOutputStream out = new FileOutputStream( file );
		
		addContent( bulletin, document );
		
		document.write( out );
		document.close();
		out.close();
		
		return file;
	}

	private void addContent( Bulletin bulletin, XWPFDocument document ) {
		
		XWPFParagraph paragraph = document.createParagraph();		
		paragraph.setAlignment( ParagraphAlignment.CENTER );
		XWPFRun run = paragraph.createRun();
		run.setText( String.format( "东营市网上中介超市【%s】项目评审选取候选名单", bulletin.getProjectName() ) );
		
		for ( Trade _t : bulletin.getVerifiedTrades() ) {
			paragraph = document.createParagraph();		
			paragraph.setAlignment( ParagraphAlignment.LEFT );
			run = paragraph.createRun();
			run.setText( _t.getSupplier().getCnname() );
		}		
		
	}
}
